﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.IO;
using Db4objects.Db4o;
using Db4objects.Db4o.Linq;
using Db4objects.Db4o.Config;

namespace BLServer
{
		/*
    public class BL
    {
        public static void ProcessComplexRequestFromDB(HttpContext context)
        {
            
            context.Response.ContentType = "text/plain";

            PostDataSet pds =
                ServerBrain.DCJS_PostDataSet.ReadObject(context.Request.InputStream) as PostDataSet;
            switch (pds.Command)
            {
                case CommandList.getprojects:
                    var pdList = from Project prj in ServerBrain.db where prj.IsHead select prj; //take headed project
                    Project pd = pdList.First<Project>();
                    //foreach (var pdEl in pdList)
                    //{
                    //    if (pd == null) pd = pdEl; //take first in chain
                    //}
                    MemoryStream ms = new MemoryStream();
                    ServerBrain.DCJS_Project.WriteObject(ms, pd);
                    string json = Encoding.Default.GetString(ms.ToArray());
                    context.Response.Write(json);
                    break;
                case CommandList.login:
                    string name = pds.Parameters[0] as string;
                    string password = pds.Parameters[1] as string;
                    var pers = from User p in ServerBrain.db
                               where ((p.Name == name) && (p.Password == password))
                               select p;
                    User per = pers.First<User>();
                    if (per != null)
                    {
                        //create credential token
                        string token = Guid.NewGuid().ToString();
                        ServerBrain.usersByID.Add(token, per);
                        context.Response.Write(token);
                    }
                    else context.Response.Write("Incorrect login or password");
                    break;
                case CommandList.getissues:
                    string recToken = pds.Parameters[0] as string;
                    if (ServerBrain.usersByID.ContainsKey(recToken))
                    {
                        string userID = ServerBrain.usersByID[recToken].ID;
                        var issues = from ProjectIssue pi in ServerBrain.db
                                     where pi.Persons.ContainsKey(userID)
                                     select pi;
                        List<ProjectIssue> piList = issues.ToList<ProjectIssue>();
                        MemoryStream ms1 = new MemoryStream();
                        ServerBrain.DCJS_ProjectIssue_List.WriteObject(ms1, piList);
                        string json1 = Encoding.Default.GetString(ms1.ToArray());
                        context.Response.Write(json1);
                    }
                    else context.Response.Write("Incorrect user's credential token");
                    break;
                case CommandList.getusers:
                    var users = from User user in ServerBrain.db select user;
                    List<User> uList = users.ToList<User>();
                    foreach (User u in uList)
                        u.Password = ""; //clear all passwords before send
                    MemoryStream ms2 = new MemoryStream();
                    ServerBrain.DCJS_User_List.WriteObject(ms2, uList);
                    string json2 = Encoding.Default.GetString(ms2.ToArray());
                    context.Response.Write(json2);
                    break;
            }            
        }
    }
		*/

    public class ServerBrain
    {
        static Dictionary<string, Action<HttpContext>> maps = new Dictionary<string, Action<HttpContext>>();

        public static Dictionary<string, User> usersByID = new Dictionary<string, User>();

				static string basePath = AppDomain.CurrentDomain.BaseDirectory;
        static string database_filename = "db.db4o";
				static string database_path = Path.Combine(basePath, database_filename);

        static void StoreExampleDataToDB(string filename)
        {
            string dbfile = filename;
            //if (File.Exists(dbfile))
            //    File.Delete(dbfile);
            var db = Db4oEmbedded.OpenFile(dbfile);
            try
            {
                User pers1 = new User("Joe", "black");
                pers1.Role = PersonRole.Admin; //one admin - for test
                db.Store(pers1);
                db.Store(new User("Jack", "123"));

                Project proj = new Project("Head", true);
                proj.IssuesIDs = new List<string>();
                ProjectIssue pid = new ProjectIssue("First Issue in the Head", ProjectIssueType.ToDo);
                pid.Persons = new Dictionary<string, PersonIssueRole>();
                pid.Persons.Add(pers1.ID, PersonIssueRole.Admin); //add pers1 as a admin of the issue
                pid.Details = new List<ProjectIssueDetail>();
                pid.Details.Add(new ProjectIssueDetail(DateTime.Now, "Oh my God!"));
                pid.Details.Add(new ProjectIssueDetail(DateTime.Now, "Oh my God too!"));
                pid.Details.Add(new ProjectIssueDetail(DateTime.Now, "Such a beautiful bug!"));
                proj.IssuesIDs.Add(pid.ID);
                db.Store(pid);

                ProjectIssue pid2 = new ProjectIssue("Secong Issue in the Head");
                pid2.Details = new List<ProjectIssueDetail>();
                pid2.Details.Add(new ProjectIssueDetail(DateTime.Now, "I've found something"));
                pid2.Details.Add(new ProjectIssueDetail(DateTime.Now, "I saw the same"));
                pid2.Persons = new Dictionary<string, PersonIssueRole>();
                pid2.Persons.Add(pers1.ID, PersonIssueRole.Reporter); //add pers1 as a reporter of the issue
                proj.IssuesIDs.Add(pid2.ID);
                db.Store(pid2);                

                proj.Subprojects = new List<Project>();
                Project proj2 = new Project("First", false);
                proj.Subprojects.Add(proj2);
                ProjectIssue pid3 = new ProjectIssue("Third Issue in the Head", ProjectIssueType.Idea);
                pid3.Persons = new Dictionary<string, PersonIssueRole>();
                pid3.Persons.Add(pers1.ID, PersonIssueRole.Reporter); //add pers1 as a reporter of the issue
                proj2.IssuesIDs = new List<string>();
                proj2.IssuesIDs.Add(pid3.ID);
                db.Store(pid3);
                proj.Subprojects.Add(new Project("Second", false));
                Project third = new Project("Third", false);
                proj.Subprojects.Add(third);
                third.Subprojects = new List<Project>();
                third.Subprojects.Add(new Project("SubThird", false));
                third.Subprojects.Add(new Project("SubThird2", false));

                db.Store(proj);
                /*
                //check what we have stored                
                var issues = from ProjectIssueDetail pidds in db select pidds;
                foreach (var issue in issues)
                {

                }
                */                
            }
            finally
            {
                db.Close();
            }
        }

        public static IEmbeddedObjectContainer db {get; private set;}
        //public static IEmbeddedObjectContainer db = Db4oEmbedded.OpenFile(database_filename);

        static private bool isInit = false;
        //static private bool isInit = true;

        public static void Init()
        {
            if (!isInit)
            {
                if (!File.Exists(database_path))
									StoreExampleDataToDB(database_path);
                IEmbeddedConfiguration config = Db4oEmbedded.NewConfiguration();
                config.Common.ObjectClass(typeof(Project)).CascadeOnUpdate(true);
                config.Common.ObjectClass(typeof(Project)).CascadeOnDelete(true);
                config.Common.ObjectClass(typeof(ProjectIssue)).CascadeOnUpdate(true);
                config.Common.ObjectClass(typeof(ProjectIssue)).CascadeOnDelete(true);
								db = Db4oEmbedded.OpenFile(config, database_path);
                isInit = true;
            }
        }

				/*
        public static void ProcessRequest(HttpContext context)
        {
            if (!isInit)
            {
                maps.Add("/WebServiceHandler.ashx", BL.ProcessComplexRequestFromDB);
                if (!File.Exists(database_filename)) 
                    StoreExampleDataToDB(database_filename);
                db = Db4oEmbedded.OpenFile(database_filename);
                isInit = true;
            }
            string path = context.Request.FilePath;
            if (maps.ContainsKey(path))
            {
                maps[path](context); //execute request
            }
        }
				*/
    }    
}
